﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using System;
namespace Zeus.Mvc
{
    using Loggers;
    using Middlewares;
    using Options;
    using Results;
    public static class ServiceDependencyInjection
    {
        public static IMvcCoreBuilder AddZeus(this IMvcCoreBuilder builder, Action<ZeusMvcOptions> zeusMvcOptionsBuilder = null)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }
            var zeusMvcOptions = new ZeusMvcOptions();
            zeusMvcOptionsBuilder?.Invoke(zeusMvcOptions);
            AddZeusService(builder.Services, zeusMvcOptions);
            builder.Services.AddSingleton(zeusMvcOptions);
            return builder;
        }

        internal static void AddZeusService(IServiceCollection services, ZeusMvcOptions zeusMvcOptions)
        {
            services.TryAddEnumerable(ServiceDescriptor.Transient<IConfigureOptions<MvcOptions>, ZeusMvcOptionSetup>());

            if (zeusMvcOptions == null)
            {
                zeusMvcOptions = new ZeusMvcOptions();
            }

            if (zeusMvcOptions.TypeOfIZeusResultExecutor != null)
            {
                services.AddTransient(typeof(IZeusResultExecutor), zeusMvcOptions.TypeOfIZeusResultExecutor);
            }

            if (zeusMvcOptions.TypeOfIZeusResultFormatter != null)
            {
                services.AddSingleton(typeof(IZeusResultFormatter), zeusMvcOptions.TypeOfIZeusResultFormatter);
            }

            if (zeusMvcOptions.TypeOfIHttpContextLogger != null)
            {
                services.AddTransient(typeof(IHttpContextLogger), zeusMvcOptions.TypeOfIHttpContextLogger);
            }
        }

        public static void UseZeus(this IApplicationBuilder applicationBuilder)
        {
            var zeusMvcOptions = applicationBuilder.ApplicationServices.GetRequiredService<ZeusMvcOptions>();

            if (zeusMvcOptions.EnableCorrelationIdMiddleware)
            {
                applicationBuilder.UseMiddleware<HttpCorrelationIdMiddleware>();
            }

            if (zeusMvcOptions.TypeOfIHttpContextLogger != null)
            {
                applicationBuilder.UseMiddleware<HttpContextLoggerMiddleware>();
            }
        }
    }
}
